package cc.fozone.note.view;

import cc.fozone.note.beans.Article;
import cc.fozone.note.configuration.IConfiguration;
import cc.fozone.note.service.IApplicationService;
import cc.fozone.note.service.IArticleService;
import cc.fozone.note.service.impl.ApplicationService;
import cc.fozone.note.view.control.ArticleCellFactory;
import cc.fozone.note.view.control.ArticleStringConverter;
import cc.fozone.note.view.control.WindowButton;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Dialog;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Region;
import org.apache.commons.lang.StringUtils;

import java.util.List;

@SuppressWarnings("deprecation")
public class NavigatorView extends BorderPane implements IView {
	private IConfiguration<String,String> configuration;
	
	private IndexView index;
	
	private double height = 60;
	private String styleClass = "navigator";
	private String logoStyleClass = "logo";
	private String paneStyleClass = "pane";
	
	private String searchStyleClass = "search";
	private String searchTextStyleClass = "search-text";
	private String searchButtonStyleClass = "search-button";
	private String searchPlaceholder = "Search";
	
	private String windowStyleClass="window";
	private String windowCloseStyleClass="window-close";
	private String windowMinStyleClass="window-min";
	private String windowMaxStyleClass="window-max";
	
	private AboutView aboutView;
	private Region logo;
	private FlowPane pane;
	private WindowButton window;
	
	private ComboBox<Article> search;
	private MenuView menu;

	protected double mouseDragOffsetX;

	protected double mouseDragOffsetY;
	
	private IApplicationService applicationService;
	private IArticleService articleService;
	
	public NavigatorView(IndexView index,IConfiguration<String,String> configuration) {
		// TODO Auto-generated constructor stub
		this.index = index;
		this.configuration = configuration;
	}
	
	@Override
	public void init() {
		// TODO Auto-generated method stub
		this.initConfiguration();
		this.buildView();
		this.buildLayout();
	}
	
	private void initConfiguration(){
		applicationService = ApplicationService.getInstane();
		articleService = applicationService.getArticleService();
		
		height = Double.parseDouble(configuration.get("app.navigator.height","60"));
		styleClass = configuration.get("app.navigator.styleClass",styleClass);
		logoStyleClass = configuration.get("app.navigator.logoStyleClass",logoStyleClass);
		paneStyleClass = configuration.get("app.navigator.paneStyleClass",paneStyleClass);
		
		searchPlaceholder = configuration.get("app.navigator.searchPlaceholder",searchPlaceholder);
		searchStyleClass = configuration.get("app.navigator.searchStyleClass",searchStyleClass);
		searchTextStyleClass = configuration.get("app.navigator.searchTextStyleClass",searchTextStyleClass);
		searchButtonStyleClass = configuration.get("app.navigator.searchButtonStyleClass",searchButtonStyleClass);
		
		windowStyleClass = configuration.get("app.navigator.windowStyleClass",windowStyleClass);
		windowCloseStyleClass = configuration.get("app.navigator.windowCloseStyleClass",windowCloseStyleClass);
		windowMinStyleClass = configuration.get("app.navigator.windowMinStyleClass",windowMinStyleClass);
		windowMaxStyleClass = configuration.get("app.navigator.windowMaxStyleClass",windowMaxStyleClass);
	}
	
	private void buildView(){
		logo = new Region();
		logo.getStyleClass().add(logoStyleClass);
		
		pane = new FlowPane();
		pane.getStyleClass().add(paneStyleClass);
		
		ObservableList<Node> paneList = pane.getChildren();
		
		//search = new SearchBox(searchPlaceholder);
		search = new ComboBox<Article>();
		search.getStyleClass().add(searchStyleClass);
		//search.addTextStyleClass(searchTextStyleClass);
		//search.addButtonClass(searchButtonStyleClass);
		search.setPromptText(searchPlaceholder);
		search.setEditable(true);
		search.setCellFactory(new ArticleCellFactory());
		search.setConverter(new ArticleStringConverter());
		
		paneList.add(search);
		
		menu = new MenuView(configuration);
		paneList.add(menu);
		
		window = new WindowButton();
		window.addCloseStyleClass(windowCloseStyleClass);
		window.addMinStyleClass(windowMinStyleClass);
		window.addMaxStyleClass(windowMaxStyleClass);
		window.getStyleClass().add(windowStyleClass);
		
		this.setPrefHeight(height);
		this.getStyleClass().add(styleClass);
		
		aboutView = new AboutView(configuration);
	}
	
	private void buildLayout(){
		this.setLeft(logo);
		this.setCenter(pane);
		this.setRight(window);
	}
	
	private void doSearch(String title) {
		if(StringUtils.isBlank(title)) {
			title = "";
		}
		List<Article> list = articleService.selectFuzzyByTitle(title);
		ObservableList<Article> items = search.getItems();
		items.clear();
		items.addAll(list);
	}
	
	@Override
	public void handle() {
		// TODO Auto-generated method stub
		this.handleWindowEvent();
		this.handleMenuEvent();
		this.handleSearchEvent();
	}
	
	private void handleWindowEvent(){
		window.setCloseOnAction(event -> {
            // TODO Auto-generated method stub
            index.getStage().close();
        });
		
		window.setMaxOnAction(event -> {
            // TODO Auto-generated method stub
            index.getStage().setMaximized(!index.getStage().isMaximized());
        });
		
		window.setMinOnAction(event -> {
            // TODO Auto-generated method stub
            index.getStage().setIconified(true);
        });
		
        // add window dragging
        this.setOnMousePressed(event -> {
            mouseDragOffsetX = event.getSceneX();
            mouseDragOffsetY = event.getSceneY();
        });
		
		this.setOnMouseDragged(event -> {
            // TODO Auto-generated method stub
            if(!index.getStage().isMaximized()) {
                index.getStage().setX(event.getScreenX() - mouseDragOffsetX);
                index.getStage().setY(event.getScreenY() - mouseDragOffsetY);
            }
        });
	}
	
	private void handleMenuEvent() {
		menu.setOnCreateAction(event -> {
            // TODO Auto-generated method stub
            ContentView content = index.getContent();
            content.resetContent();
        });
		
		menu.setOnAboutAction(event -> {
            // TODO Auto-generated method stub
            Dialog about = new Dialog();
            about.setGraphic(aboutView);
            about.showAndWait();
        });
	}
	
	private void handleSearchEvent() {
		// TODO Auto-generated method stub
		search.setOnShowing(event -> {
            // TODO Auto-generated method stub
            String title = search.getEditor().getText();
            NavigatorView.this.doSearch(title);
        });
		search.setOnAction(event -> {
            // TODO Auto-generated method stub
            /*
            SingleSelectionModel<Article> model = search.getSelectionModel();
            Article article = model.getSelectedItem();
            */
            Article article = search.getValue();
            if(article == null) {
                return ;
            }
            long id = article.getId();
            if(id <= 0) {
                if(search.isFocused()) {
                    search.show();
                }
                return ;
            }

            index.getContent().loadArticle(id);
        });
		
		search.setValue(new Article());
	}
}
